package com.hoo.permission.sdk.web.security.shiro;

import com.hoo.permission.sdk.web.security.jwt.HooJWTToken;
import com.hoo.permission.sdk.web.security.jwt.HooJwtTools;
import com.hoo.permission.sdk.server.domain.entity.SysUser;
import com.hoo.permission.sdk.server.domain.model.LoginUser;
import com.hoo.permission.sdk.server.manager.IPermissionService;
import com.hoo.permission.sdk.server.service.ISysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * HooRealm
 *
 * @author hank
 * @create 2020-11-12 上午10:21
 **/
@Component
public class HooRealm extends AuthorizingRealm {

    @Autowired ISysUserService userService;

    @Autowired IPermissionService permissionService;

    @Autowired HooJwtTools jwtTools;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof HooJWTToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // TODO 根据用户名称，查询对应的权限，特殊处理：SUPER_ADMIN 目前可拥有 *:*:*
        // 存 LoginUser, 同时缓存
        LoginUser loginUser = (LoginUser) principalCollection.getPrimaryPrincipal();
        Set<String> permissions =  permissionService.getPermissions(loginUser.getId());
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setStringPermissions(permissions);

        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取用户
        String token = (String) authenticationToken.getPrincipal();
        LoginUser loginUser = jwtTools.getLoginUser(token);
        try {
            SysUser user = userService.getByUserName(loginUser.getUsername());
            loginUser.setPassword(user.getPassword());
        }catch (Exception e) {
            throw new AuthenticationException("认证时发生异常:" + e.getCause().getMessage());
        }
        if(!jwtTools.verify(token, loginUser)){
            throw new AuthenticationException("认证非法");
        }
        return new SimpleAuthenticationInfo(loginUser, token, loginUser.getUsername());
    }

}
